package com.tengju.bff.interfaces.covercharge.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.idanchuang.component.config.apollo.util.ConfigUtil;
import com.tengju.bff.interfaces.covercharge.constant.*;
import com.tengju.bff.interfaces.covercharge.dto.BankInfo;
import com.tengju.bff.interfaces.covercharge.entity.dto.*;
import com.tengju.bff.interfaces.covercharge.entity.po.*;
import com.tengju.bff.interfaces.covercharge.entity.vo.*;
import com.tengju.bff.interfaces.covercharge.enums.ProfitTypeEnum;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceLetaxWithdrawLogMapper;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceTaskMapper;
import com.tengju.bff.interfaces.covercharge.mapper.ServiceWithdarwCycleAddMapper;
import com.tengju.bff.interfaces.covercharge.service.*;
import com.tengju.bff.interfaces.covercharge.util.DateTimeUtils;
import com.tengju.bff.interfaces.covercharge.util.OssUtil;
import com.tengju.bff.interfaces.shared.InterfaceException;
import com.tengju.settlement.application.shared.ApplicationException;
import com.tengju.settlement.application.shared.ApplicationExceptionCode;
import com.tengju.settlement.domain.model.account.AccountId;
import com.tengju.settlement.domain.model.depository.DepositoryChannel;
import com.tengju.settlement.domain.shared.Amount;
import com.tengju.user.application.sms.SmsBizService;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.service.UserDocService;
import com.zoi7.component.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.tengju.bff.interfaces.shared.InterfaceCode.USER_NOT_EXIST;

/**
 * <p>
 * 乐税个体户体现明细表 服务实现类
 * </p>
 *
 * @author zhaoyi
 * @since 2020-02-24
 */
@Service
@Slf4j
public class ServiceLetaxWithdrawLogServiceImpl extends ServiceImpl<ServiceLetaxWithdrawLogMapper, ServiceLetaxWithdrawLog> implements IServiceLetaxWithdrawLogService {

    //每页数量
    private final static Integer PAGE_SIZE = 40000;

    @Autowired
    private ServiceLetaxWithdrawLogMapper serviceLetaxWithdrawLogMapper;

    @Autowired
    private IServiceLetaxRegisteredService serviceLetaxRegisteredService;

    @Autowired
    @Lazy
    private IServiceWithdarwCycleAddService serviceWithdarwCycleAddService;

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private UserDocService userDocService;

    @Autowired
    private IServiceAccountService accountService;

    @Autowired
    private IServiceWithdrawFlowService withdrawFlowService;

    @Autowired
    private SmsBizService smsBizService;

    @Autowired
    private UserService userService;

    @Autowired
    private ServiceTaskMapper taskMapper;

    @Autowired
    private IServiceWithdarwCycleAddTransOrderService serviceWithdarwCycleAddTransOrderService;

    @Autowired
    @Lazy
    private ServiceWithdarwCycleAddServiceImpl serviceWithdarwCycleAddServiceImpl;

    @Autowired
    private IServiceWithdarwCycleAddTransOrderService cycleAddTransOrderService;

    @Autowired
    private ServiceAccountServiceImpl serviceAccountService;
    @Autowired
    private ServiceWithdarwCycleAddMapper serviceWithdarwCycleAddMapper;

    @Value("${depository.account.whiteList}")
    private String DepAccountWhiteList;


    @Override
    public List<WithdrawRecordVo> getWithdrawList(Integer idCode, String platformCode, String type, String dateTime) {
        List<WithdrawRecordVo> lists = serviceLetaxWithdrawLogMapper.getWithdrawList(idCode, platformCode, type, dateTime);
        for (WithdrawRecordVo vo : lists) {
            LetaxWithdrawStatusEnum letaxWithdrawStatusEnum = LetaxWithdrawStatusEnum.getStatusDesc(vo.getStatus());
            vo.setStatusName(letaxWithdrawStatusEnum != null ? letaxWithdrawStatusEnum.getDesc() : vo.getStatus() + "");
            vo.setIdentity(type);
        }
        return lists;
    }

    @Override
    public List<WithdrawRecordVo> withdrawListByTime(Integer idCode, String platformCode, String type, String startTime, String endTime) {
        List<WithdrawRecordVo> lists = serviceLetaxWithdrawLogMapper.withdrawListByTime(idCode, platformCode, type, startTime, endTime);
        for (WithdrawRecordVo vo : lists) {
            LetaxWithdrawStatusEnum letaxWithdrawStatusEnum = LetaxWithdrawStatusEnum.getStatusDesc(vo.getStatus());
            vo.setStatusName(letaxWithdrawStatusEnum != null ? letaxWithdrawStatusEnum.getDesc() : vo.getStatus() + "");
            vo.setIdentity(type);
        }
        return lists;
    }

    @Override
    public List<ServiceLetaxWithdrawLog> queryPersonApplyList(String idCode, String cardNo, String platformCode,
                                                              Integer status, String startDate, String endDate) {
        QueryWrapper<ServiceLetaxWithdrawLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(idCode), "id_code", idCode);
        queryWrapper.eq(StringUtils.isNotBlank(platformCode), "platform_code", platformCode);
        queryWrapper.eq(status != null, "status", status);
        queryWrapper.ge(StringUtils.isNotBlank(startDate), "created_at", startDate);
        queryWrapper.lt(StringUtils.isNotBlank(endDate), "created_at", endDate);
        queryWrapper.like(StringUtils.isNotBlank(cardNo), "registered_info", cardNo);
        queryWrapper.eq("auth_type", "person");
        List<ServiceLetaxWithdrawLog> applyList = serviceLetaxWithdrawLogMapper.selectList(queryWrapper);
        return applyList;
    }

    @Override
    public List<ServiceLetaxWithdrawLog> queryRegisterApplyList(String idCode, String cardNo, String platformCode,
                                                                String taxNo, Integer status, String startDate, String endDate) {
        QueryWrapper<ServiceLetaxWithdrawLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(idCode), "id_code", idCode);
        queryWrapper.eq(StringUtils.isNotBlank(platformCode), "platform_code", platformCode);
        queryWrapper.eq(status != null, "status", status);
        queryWrapper.ge(StringUtils.isNotBlank(startDate), "created_at", startDate);
        queryWrapper.lt(StringUtils.isNotBlank(endDate), "created_at", endDate);
        queryWrapper.like(StringUtils.isNotBlank(cardNo), "registered_info", cardNo);
        queryWrapper.like(StringUtils.isNotBlank(taxNo), "registered_info", taxNo);
        queryWrapper.eq("auth_type", "regist_soho");
        List<ServiceLetaxWithdrawLog> applyList = serviceLetaxWithdrawLogMapper.selectList(queryWrapper);
        return applyList;
    }

    @Override
    public Page<WithdrawLogRecordVo> queryPageByIdCode(Page page, String idCode, String status) {
        return page.setRecords(serviceLetaxWithdrawLogMapper.queryPageByIdCode(page, idCode, status));
    }

    @Override
    public BigDecimal getIssuedAmount(Integer idCode, String platformCode, String type, String dateTime) {
        return serviceLetaxWithdrawLogMapper.getIssuedAmount(idCode, platformCode, type, dateTime);
    }

    @Override
    public BigDecimal getBeIssuedAmount(Integer idCode, String platformCode, String type, String dateTime) {
        return serviceLetaxWithdrawLogMapper.getBeIssuedAmount(idCode, platformCode, type, dateTime);
    }


    @Override
    public Page<AdminRegistrationQueryVo> queryPageRegistration(Page page, String idCode, String name, String taxNo, String cardNo, String platform, Integer status, String startDate, String endDate) {
        QueryWrapper<ServiceLetaxWithdrawLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(idCode), "id_code", idCode);
        queryWrapper.eq(StringUtils.isNotBlank(platform), "platform_code", platform);
        queryWrapper.eq(status != null, "status", status);
        queryWrapper.ge(StringUtils.isNotBlank(startDate), "created_at", startDate);
        queryWrapper.lt(StringUtils.isNotBlank(endDate), "created_at", endDate);
        queryWrapper.like(StringUtils.isNotBlank(name), "registered_info", name);
        queryWrapper.like(StringUtils.isNotBlank(taxNo), "registered_info", taxNo);
        queryWrapper.like(StringUtils.isNotBlank(cardNo), "registered_info", cardNo);
        queryWrapper.eq("auth_type", "regist_soho");
        queryWrapper.orderByDesc("id");
        IPage<ServiceLetaxWithdrawLog> pagelist = serviceLetaxWithdrawLogMapper.selectPage(page, queryWrapper);
        List<ServiceLetaxWithdrawLog> logs = pagelist.getRecords();
        List<AdminRegistrationQueryVo> querys = new ArrayList<>();
        for (ServiceLetaxWithdrawLog log : logs) {
            AdminRegistrationQueryVo query = new AdminRegistrationQueryVo();
            BeanUtils.copyProperties(log, query);
            List<RegisteredInfo> infos = JSON.parseArray(log.getRegisteredInfo(), RegisteredInfo.class);
            for (RegisteredInfo info : infos) {
                query.setName(info.getName());
                query.setBankName(info.getBankName());
                query.setBankNo(info.getBankNo());
                query.setIdcardName(info.getIdcardName());
                query.setMobile(info.getPhoneNumber());
                //注册工商户多余信息
                query.setMerchantName(info.getMerchantName());
                query.setMerchantTaxNumber(info.getMerchantTaxNumber());
                query.setChannel(Optional.ofNullable(DepositoryChannel.ofInnerCode(info.getDepositoryChannel())).map(DepositoryChannel::getDesc).orElse(""));
            }
            querys.add(query);
        }
        page.setRecords(querys);
        page.setTotal(pagelist.getTotal());
        return page;
    }

    /**
     * 查询个体发放列表
     *
     * @param page              分页参数
     * @param personalGiveQuery 个体发放查询
     */
    @Override
    public Page<PersonalGiveVo> queryPersonalGiveList(Page<PersonalGiveVo> page, PersonalGiveQuery personalGiveQuery) {
        if (StringUtils.isNotEmpty(personalGiveQuery.getCycleDate()) && !"null".equals(personalGiveQuery.getCycleDate())) {
            String cycleDay = ConfigUtil.getConfig().getString("withdraw.cycle.day", "10");
            String startDateStr = DateTimeUtils.parseDateAsString(
                    DateTimeUtils.addMonths(DateUtil.parse(personalGiveQuery.getCycleDate(), DateTimeUtils.MONTH_FORMAT), -1),
                    DateTimeUtils.MONTH_FORMAT)
                    + "-" + (Integer.parseInt(cycleDay) + 1) + " 00:00:00";

            String endDateStr = DateTimeUtils.parseDateAsString(
                    DateUtil.parse(personalGiveQuery.getCycleDate(), DateTimeUtils.MONTH_FORMAT),
                    DateTimeUtils.MONTH_FORMAT)
                    + "-" + cycleDay + " 23:59:59";
            personalGiveQuery.setStartDate(startDateStr);
            personalGiveQuery.setEndDate(endDateStr);
        } else {
            personalGiveQuery.setCycleDate(null);
        }

        if (StringUtils.isNotEmpty(personalGiveQuery.getMobile())) {
            try {
                UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(null, personalGiveQuery.getMobile());
                Assert.isTrue(userInfo != null, "没有查询到用户信息");
                personalGiveQuery.setIdCode(Integer.parseInt(userInfo.getIdCode() + ""));
            } catch (Exception e) {
                throw new InterfaceException(USER_NOT_EXIST);
            }
        }

        List<PersonalGiveVo> list = serviceLetaxWithdrawLogMapper.queryPersonalGiveList(page, personalGiveQuery);
        List<UserIdCode> idList = new ArrayList<>();
        List<ServiceLetaxRegisteredDto> idCodeList = new ArrayList<>();
        for (PersonalGiveVo personalGiveVo : list) {
            idList.add(new UserIdCode(personalGiveVo.getIdCode()));

            if (SignIdentityEnum.regist_soho.toString().equals(personalGiveVo.getAuthType())) {
                idCodeList.add(new ServiceLetaxRegisteredDto(personalGiveVo.getIdCode()));
            }
        }

        Map<Integer, Boolean> commonMap = new HashMap<>();
        try {
            commonMap = serviceLetaxRegisteredService.getNumberCommon(idCodeList);
        } catch (Exception e) {
            log.error("getNumberCommon error", e);
        }

        Map<UserIdCode, UserInfo> userMap = userService.queryUserMap(idList);

        for (PersonalGiveVo personalGiveVo : list) {
            UserIdCode userId = new UserIdCode(personalGiveVo.getIdCode());
            if (userMap.containsKey(userId)) {
                UserInfo userVO = userMap.get(userId);
                personalGiveVo.setMobile(userVO.getMobile());
                personalGiveVo.setName(userVO.getName());
            }
            if (StringUtils.isNotEmpty(personalGiveQuery.getCycleDate())) {
                personalGiveVo.setCycleDate(personalGiveQuery.getCycleDate());
            } else {
                personalGiveVo.setCycleDate(DateTimeUtils.parseDateAsString(
                        DateTimeUtils.addMonths(personalGiveVo.getStartAt(), 1)
                        , DateTimeUtils.MONTH_FORMAT));
            }

            if (commonMap.containsKey(personalGiveVo.getIdCode())) {
                personalGiveVo.setCommon("是");
            } else {
                personalGiveVo.setCommon("否");
            }

            //乐税注销状态
            String letaxStatus = LetaxWithdrawMerchantStatusEnum.getStatusDesc(personalGiveVo.getLetaxStatus()).getDesc();
            if (letaxStatus == null) {
                personalGiveVo.setLetaxStatusStr("空");
            } else {
                personalGiveVo.setLetaxStatusStr(letaxStatus);
            }

            String registeredInfoStr = personalGiveVo.getRegisteredInfo();
            if (SignIdentityEnum.person.toString().equals(personalGiveVo.getAuthType())) {
                BankInfo bankInfo = JSON.parseObject(registeredInfoStr, BankInfo.class);
                personalGiveVo.setIdcardName(bankInfo.getIdcardName());
                personalGiveVo.setIdcardNo(bankInfo.getIdcardNo());
                personalGiveVo.setBankName(bankInfo.getBankName());
                personalGiveVo.setBankNo(bankInfo.getBankNo());
                personalGiveVo.setAuthType("个人");
            } else if (SignIdentityEnum.regist_soho.toString().equals(personalGiveVo.getAuthType())) {
                List<RegisteredInfo> registeredInfoList = JSON.parseArray(registeredInfoStr, RegisteredInfo.class);
                if (CollectionUtil.isNotEmpty(registeredInfoList)) {
                    RegisteredInfo registeredInfo = registeredInfoList.get(0);
                    personalGiveVo.setIdcardName(registeredInfo.getIdcardName());
                    personalGiveVo.setIdcardNo(registeredInfo.getIdcardNo());
                    personalGiveVo.setBankName(registeredInfo.getBankName());
                    personalGiveVo.setBankNo(registeredInfo.getBankNo());
                    personalGiveVo.setMerchantName(registeredInfo.getMerchantName());
                    personalGiveVo.setMerchantTaxNumber(registeredInfo.getMerchantTaxNumber());
                    personalGiveVo.setChannel(Optional.ofNullable(DepositoryChannel.ofInnerCode(registeredInfo.getDepositoryChannel()))
                            .map(DepositoryChannel::getDesc).orElse(""));
                }
                personalGiveVo.setAuthType("注册个体户");
            }
            personalGiveVo.setFee(personalGiveVo.getPassMoney().multiply(personalGiveVo.getRatio()));
            personalGiveVo.setMoney(personalGiveVo.getPassMoney().subtract(personalGiveVo.getFee()));
            personalGiveVo.setRegisteredInfo(null);

            if (LetaxWithdrawStatusEnum.PUT.getCode().equals(personalGiveVo.getStatus())) {
                personalGiveVo.setStatusStr("发放成功");
            } else if (LetaxWithdrawStatusEnum.PUTFAIL.getCode().equals(personalGiveVo.getStatus())) {
                personalGiveVo.setStatusStr("发放失败");
            } else if (LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode().equals(personalGiveVo.getStatus())) {
                personalGiveVo.setStatusStr("发放失败-银行卡已修改");
            } else {
                //申请金额为0，且已审核金额大于0
                if (BigDecimal.ZERO.compareTo(personalGiveVo.getApplyMoney()) == 0
                        && BigDecimal.ZERO.compareTo(personalGiveVo.getPassMoney()) < 0) {
                    personalGiveVo.setStatusStr("待发放");
                    personalGiveVo.setStatus(PersonalGiveStatusEnum.PASS.getCode());
                } else {
                    personalGiveVo.setStatusStr("待审核");
                    personalGiveVo.setStatus(PersonalGiveStatusEnum.APPLY.getCode());
                }
            }

            /*if (StringUtils.isNotEmpty(personalGiveVo.getChannel())) {
                personalGiveVo.setChannel(PersonalGiveChannelEnum.getDesc(personalGiveVo.getChannel()));
            }*/

            //个人按钮或者乐税注销了的
            personalGiveVo.setIsPersonalButton(false);
            //提现是个人,且是待发放或者银行卡已修改
            if (personalGiveVo.getAuthType().equals(SignIdentityEnum.person.getDesc()) && (LetaxWithdrawStatusEnum.PASS.getCode().equals(personalGiveVo.getStatus()) || LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode().equals(personalGiveVo.getStatus()))) {
                personalGiveVo.setIsPersonalButton(true);
            }
            //乐税注销了
            if (SignIdentityEnum.regist_soho.getDesc().equals(personalGiveVo.getAuthType()) && (LetaxWithdrawStatusEnum.PASS.getCode().equals(personalGiveVo.getStatus()) || LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode().equals(personalGiveVo.getStatus())) && LetaxWithdrawMerchantStatusEnum.YES.getCode().equals(personalGiveVo.getLetaxStatus()) && serviceWithdarwCycleAddTransOrderService.getNotFailNum(personalGiveVo.getCycleAddId()).equals(0)) {
                personalGiveVo.setIsPersonalButton(true);
            }

            //变更打款状态按钮
            personalGiveVo.setIsUnknownButton(false);
            //提现是注册个体户且状态为未知或者处理中且错误次数等于或者超过六次或者(交易表为成功且周期表为不成功)。都需要显示变更打款状态按钮
            if (personalGiveVo.getAuthType().equals(SignIdentityEnum.regist_soho.getDesc()) && (Objects.nonNull(serviceWithdarwCycleAddTransOrderService.getProcessOrUnKnow(personalGiveVo.getCycleAddId(), true)) || (Objects.nonNull(serviceWithdarwCycleAddTransOrderService.getSuccessful(personalGiveVo.getCycleAddId())) && !personalGiveVo.getStatus().equals(ServiceWithdarwCycleAddEnum.HAVE_PAY.getCode())))
            ) {
                personalGiveVo.setIsUnknownButton(true);
            }

            //打款按钮
            personalGiveVo.setIsPayButton(false);
            //乐税提现且乐税状态未注销且(审核通过或者打款失败或者账户已修改)且交易记录表没有成功，未知和处理中
            if (personalGiveVo.getAuthType().equals(SignIdentityEnum.regist_soho.getDesc()) && LetaxWithdrawMerchantStatusEnum.NO.getCode().equals(personalGiveVo.getLetaxStatus()) && (personalGiveVo.getStatus().equals(LetaxWithdrawStatusEnum.PASS.getCode()) || personalGiveVo.getStatus().equals(LetaxWithdrawStatusEnum.PUTFAIL.getCode()) || personalGiveVo.getStatus().equals(LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode())) && serviceWithdarwCycleAddTransOrderService.getNotFailNum(personalGiveVo.getCycleAddId()).equals(0)) {
                personalGiveVo.setIsPayButton(true);
            }
        }

        page.setRecords(list);
        return page;
    }


    /**
     * 获取企业网银信息
     *
     * @param personalGive excel数据
     */
    private PersonalGiveInfo getPersonalGiveInfo(String[] personalGive, String channel) {
        if (PersonalGiveChannelEnum.EBANK.getCode().equals(channel)) {
            Assert.isTrue(personalGive.length == 10, "列数需为10列，请检查excel是否正确");
            //第二列：所属周期
            String cycleDate = personalGive[1];
            //第三列：代理ID
            Integer idCode = Integer.parseInt(personalGive[2]);
            //第四列：商户平台
            String platformCode = this.parsePlatformCode(personalGive[3]);
            //第五列：银行卡号
            String bankNo = personalGive[4];

            //第8列：金额
            BigDecimal money = new BigDecimal(personalGive[7]);
            //第9列：状态
            int status = Integer.parseInt(personalGive[8]);
            //第10列：错误信息
            String msg = personalGive[9];
            return new PersonalGiveInfo(cycleDate, idCode, platformCode, bankNo, money, status, msg, null, null);
        } else if (PersonalGiveChannelEnum.CLOUD.getCode().equals(channel)) {
            Assert.isTrue(personalGive.length == 12, "列数需为12列，请检查excel是否正确");

            //第二列：所属周期
            String cycleDate = personalGive[1];
            //第三列：代理ID
            Integer idCode = Integer.parseInt(personalGive[2]);
            //第4列：银行卡号
            String bankNo = personalGive[3];
            //第5列：身份证号
            String idcardNo = personalGive[4];
            //第7列：商户平台
            String platformCode = this.parsePlatformCode(personalGive[6]);
            //第8列：打款金额
            BigDecimal money = new BigDecimal(personalGive[7]);
            //第10列：状态
            String statusStr = personalGive[9];
            int status;
            if ("已打款".equals(statusStr)) {
                status = 0;
            } else {
                status = 1;
            }
            //第11列：错误信息
            String msg = personalGive[10];
            //第12列：网银流水
            String uuid = personalGive[11];
            return new PersonalGiveInfo(cycleDate, idCode, platformCode, bankNo, money, status, msg, idcardNo, uuid);
        } else {
            throw new RuntimeException("打款渠道错误");
        }

    }


    @Override
    public PersonalGiveImportTaskResult importPersonalGiveCreateTask(int allSize, PersonalGiveImport personalGiveImport) {
        ServiceTask task = new ServiceTask();
        task.setTaskNo(String.valueOf(IdWorker.getId())).setTaskKey(personalGiveImport.getCycleDate() + "_" + personalGiveImport.getFileName())
                .setBizType(TaskBizType.TYPE_1.getType()).
                setTaskSize(allSize).setTaskStatus(1).setTaskApplicant(personalGiveImport.getApplicant())
                .setCreateTime(LocalDateTime.now()).setUpdateTime(LocalDateTime.now());
        int num = taskMapper.insert(task);
        PersonalGiveImportTaskResult taskResult = new PersonalGiveImportTaskResult();
        if (num > 0) {
            taskResult.setTaskResult(true);
            taskResult.setTaskNo(task.getTaskNo());
            taskResult.setTaskKey(task.getTaskKey());
            return taskResult;
        }
        taskResult.setTaskResult(false);
        taskResult.setErrorMsg("创建任务失败，请稍后重试");
        return taskResult;
    }


    /**
     * 导入个体发放状态
     *
     * @param personalGiveInfo   个体发放信息
     * @param personalGiveImport 个体发放类型
     */
    @Override
    public void importPersonalGive(String taskNo, List<String[]> personalGiveInfo, PersonalGiveImport personalGiveImport) {
        //任务更新健
        ServiceTask updateTask = new ServiceTask();
        updateTask.setTaskNo(taskNo);

        Map<String, Object> cycleDateMap = new HashMap<>();
        Map<String, Object> merchantMap = new HashMap<>();
        List<PersonGiveResult> successCycleAddIdList = new ArrayList<>();
        List<PersonGiveResult> failCycleAddIdList = new ArrayList<>();
        List<String> errorMsg = Lists.newArrayList();
        //第二行算起
        int startRow = 1;

        boolean checkFlag = true;
        try {
            for (int i = startRow; i < personalGiveInfo.size(); i++) {
                log.info("导入打款数据处理，第{}行.", i + 1);
                //处理一条更新一条
                ServiceTask task = new ServiceTask();
                task.setDealSize(i).setUpdateTime(LocalDateTime.now());
                taskMapper.update(task, new UpdateWrapper<>(updateTask));

                String[] personalGive = personalGiveInfo.get(i);
                int lineNumber = (i + 1);
                if (StringUtils.isEmpty(personalGive[1])) {
                    errorMsg.add("第" + lineNumber + "行所属周期为空;");
                    continue;
                }
                PersonalGiveInfo personalGiveDto = this.getPersonalGiveInfo(personalGive, personalGiveImport.getChannel());
                //提现周期
                String cycleDate = personalGiveDto.getCycleDate();
                cycleDateMap.put(cycleDate, cycleDate);

                if (cycleDateMap.size() > 1) {
                    checkFlag = false;
                    errorMsg.add("所属周期重复");
                    break;
                }

                if (!cycleDateMap.containsKey(personalGiveImport.getCycleDate())) {
                    checkFlag = false;
                    errorMsg.add("所属周期不正确，预期值：" + personalGiveImport.getCycleDate() + "实际值：" + cycleDateMap.keySet().toArray()[0]);
                    break;
                }

                //商户平台
                String platform = personalGiveDto.getPlatformCode();
                merchantMap.put(platform, platform);

                if (merchantMap.size() > 1) {
                    checkFlag = false;
                    errorMsg.add("商户平台重复");
                    break;
                }

                if (!merchantMap.containsKey(personalGiveImport.getPlatformCode())) {
                    checkFlag = false;
                    errorMsg.add("商户平台不正确");
                    break;
                }

                // 所属周期
                //String cycleDate = personalGiveDto.getCycleDate();
                // 代理ID
                Integer idCode = personalGiveDto.getIdCode();
                // 平台
                String platformCode = personalGiveDto.getPlatformCode();
                // 银行卡号
                String bankNo = personalGiveDto.getBankNo();
                // 金额
                BigDecimal money = personalGiveDto.getMoney();
                // 状态
                int status = personalGiveDto.getStatus();
                //第10列：错误信息
                String msg = personalGiveDto.getMsg();

                PersonalGiveQuery personalGiveQuery = new PersonalGiveQuery();
                personalGiveQuery.setIdCode(idCode);
                personalGiveQuery.setCycleDate(cycleDate);
                personalGiveQuery.setPlatformCode(platformCode);
                Page<PersonalGiveVo> pageList = this.queryPersonalGiveList(new Page<>(1, 1), personalGiveQuery);

                if (CollectionUtil.isEmpty(pageList.getRecords())) {
                    errorMsg.add("第" + lineNumber + "行记录不存在;");
                    continue;
                }
                PersonalGiveVo personalGiveVo = pageList.getRecords().get(0);

                if (LetaxWithdrawStatusEnum.PUT.getCode().equals(personalGiveVo.getStatus())) {
//                invalidBuffer.append("第").append(index).append("行记录已经处理").append(";");
                    continue;
                }

                if (PersonalGiveStatusEnum.APPLY.getCode().equals(personalGiveVo.getStatus())) {
                    errorMsg.add("第" + lineNumber + "行记录未审核完成;");
                    continue;
                }

                if (PersonalGiveStatusEnum.PUTFAIL.getCode().equals(personalGiveVo.getStatus())) {
                    errorMsg.add("第" + lineNumber + "行记录已提现失败,无法再发起;");
                    continue;
                }


                if (personalGiveVo.getMoney().compareTo(money) != 0) {
                    errorMsg.add("第" + lineNumber + "行记录应付金额不一致;");
                    continue;
                }

                if (!personalGiveVo.getBankNo().equals(bankNo)) {
                    errorMsg.add("第" + lineNumber + "行银行卡号不一致;");
                    continue;
                }

                if (StringUtils.isNotEmpty(personalGiveDto.getIdcardNo())) {
                    if (!personalGiveVo.getIdcardNo().equals(personalGiveDto.getIdcardNo())) {
                        errorMsg.add("第" + lineNumber + "行身份证号不一致;");
                        continue;
                    }
                }
                boolean hitWhiteList = false;
                if (!org.springframework.util.StringUtils.isEmpty(DepAccountWhiteList)) {
                    List<UserIdCode> whiteIdCodeList = Arrays.stream(DepAccountWhiteList.split(","))
                            .map(Long::parseLong)
                            .map(UserIdCode::new)
                            .collect(Collectors.toList());
                    hitWhiteList = whiteIdCodeList.contains(new UserIdCode(idCode));
                }


                //乐税打款并且是注销的，并且交易表无正在打款的数据   命中白名单
                if (SignIdentityEnum.regist_soho.getDesc().equals(personalGiveVo.getAuthType())
                        && (LetaxWithdrawMerchantStatusEnum.NO.getCode().equals(personalGiveVo.getLetaxStatus())
                        || serviceWithdarwCycleAddTransOrderService.getNotFailNum(personalGiveVo.getCycleAddId()) > 0) &&  !hitWhiteList) {
                    continue;
                }

                if (status == 1) {
                    //失败
                    failCycleAddIdList.add(new PersonGiveResult(personalGiveVo.getBankNo(), personalGiveVo.getIdcardName(), personalGiveVo.getPassMoney(),
                            personalGiveVo.getCycleAddId(), personalGiveVo.getAccountId(), idCode, platformCode, msg));
                } else if (status == 0) {
                    //成功
                    successCycleAddIdList.add(new PersonGiveResult(personalGiveVo.getBankNo(), personalGiveVo.getIdcardName(), personalGiveVo.getPassMoney(), personalGiveVo.getCycleAddId(),
                            personalGiveVo.getAccountId(), idCode, platformCode, StringUtils.isNotEmpty(personalGiveDto.getUuid()) ? personalGiveDto.getUuid() : msg));
                }
            }

            log.info("导入打款数据处理完成,checkFlag:{}", checkFlag);
            if (!checkFlag) {
                ServiceTask task = new ServiceTask();
                task.setSuccessSize(0).setFailSize(0).setTaskErrorMsg(errorMsg.get(0)).setTaskStatus(3)
                        .setUpdateTime(LocalDateTime.now());
                taskMapper.update(task, new UpdateWrapper<>(updateTask));
                return;
            }
            int successCount = 0;
            int failureCount = 0;
            int taskStatus;
            String errMsg = null;
            try {
                String sucFailNum = this.dealData(successCycleAddIdList, failCycleAddIdList, personalGiveImport);
                successCount = Integer.valueOf(sucFailNum.split("_")[0]);
                failureCount = Integer.valueOf(sucFailNum.split("_")[1]);
                taskStatus = 2;
            } catch (Exception e) {
                log.error("导入打款数据状态更新异常");
                taskStatus = 3;
                errMsg = "导入打款数据状态更新异常";
            }
            ServiceTask task = new ServiceTask();
            task.setSuccessSize(successCount).setFailSize(failureCount)
                    .setTaskErrorMsg(errMsg)
                    .setTaskStatus(taskStatus).setUpdateTime(LocalDateTime.now());
            if (errorMsg.size() <= 10) {
                task.setTaskErrorMsg(StringUtils.join(errorMsg.toArray(), ""));
            } else {
                //上传文件
                task.setTaskErrorMsg("错误信息太多，只取前10条:" + StringUtils.join(errorMsg.subList(0, 10), "\n"));
                ByteArrayInputStream inputStream = new ByteArrayInputStream(StringUtils.join(errorMsg.toArray(), "\n").getBytes());
                String fileKey = OssUtil.uploadObjectByInputStream(inputStream, "errorMsg", updateTask.getTaskNo() + ".txt");
                task.setDownloadUrl(fileKey);
            }
            taskMapper.update(task, new UpdateWrapper<>(updateTask));
        } catch (Exception e) {
            log.error("导入打款数据处理异常:", e);
            ServiceTask task = new ServiceTask();
            String error = "导入打款数据处理异常:" + e.getMessage().substring(0, e.getMessage().length() > 300 ? 300 : e.getMessage().length());
            task.setSuccessSize(0).setFailSize(0).setTaskErrorMsg(error).setTaskStatus(3)
                    .setUpdateTime(LocalDateTime.now());
            taskMapper.update(task, new UpdateWrapper<>(updateTask));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public String dealData(List<PersonGiveResult> successCycleAddIdList, List<PersonGiveResult> failCycleAddIdList, PersonalGiveImport personalGiveImport) {
        log.info("导入打款数据校验结束,successCycleAddIdList:{},failCycleAddIdList：{}", successCycleAddIdList.size(), failCycleAddIdList.size());
        //更新成功的记录
        int successCount;
        try {
            successCount = this.updateSuccessWithdarw(successCycleAddIdList, personalGiveImport.getCreator(), personalGiveImport.getChannel());
        } catch (Exception e) {
            log.error("更新打款成功状态异常", e);
            throw e;
        }
        //更新失败的记录
        int failureCount;
        try {
            failureCount = this.updateFailWithdarw(failCycleAddIdList, personalGiveImport.getCreator(), personalGiveImport.getChannel());
        } catch (Exception e) {
            log.error("更新打款失败状态异常", e);
            throw e;
        }
        log.info("更新打款状态结束，successCount，{}，failureCount：{}", successCount, failureCount);
        return successCount + "_" + failureCount;
        //return ApiResponse.newSuccess("【更新打款状态总计" + (successCount + failureCount) + "条】" + invalidBuffer.toString());
    }

    /**
     * 转账退票
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void transferRevoke(String businessNo) {
        ServiceWithdarwCycleAddTransOrder cycleAddTransOrder = cycleAddTransOrderService.getByBusinessNo(businessNo);
        if (cycleAddTransOrder == null) {
            throw ApplicationException.error(ApplicationExceptionCode.CYCLE_ADD_TRANS_ORDER_NOT_FOUND);
        }


        ServiceWithdarwCycleAdd withdarwCycleAdd =
                serviceWithdarwCycleAddMapper.getByCycleAddId(cycleAddTransOrder.getCycleAddId());

        //发放失败 审核拒绝 取消  不做处理
        if (LetaxWithdrawStatusEnum.PUTFAIL.getCode().equals(withdarwCycleAdd.getWithdrawStatus()) ||
                LetaxWithdrawStatusEnum.CANCEL.getCode().equals(withdarwCycleAdd.getWithdrawStatus()) ||
                LetaxWithdrawStatusEnum.REJECT.getCode().equals(withdarwCycleAdd.getWithdrawStatus())) {
            return;
        }

        //更新提现日志 失败
        ServiceLetaxWithdrawLog letaxWithdrawLogUp = new ServiceLetaxWithdrawLog();
        letaxWithdrawLogUp.setStatus(LetaxWithdrawStatusEnum.PUTFAIL.getCode());
        UpdateWrapper<ServiceLetaxWithdrawLog> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("cycle_add_id", List.of(cycleAddTransOrder.getCycleAddId()));
        updateWrapper.in("status", withdarwCycleAdd.getWithdrawStatus());
        this.update(letaxWithdrawLogUp, updateWrapper);


        //已发放
        if (LetaxWithdrawStatusEnum.PUT.getCode().equals(withdarwCycleAdd.getWithdrawStatus()) ) {
            //更新提现日志 失败
            ServiceWithdrawFlow serviceWithdrawFlow = new ServiceWithdrawFlow();
            serviceWithdrawFlow.setStatus(CoverChargeEnum.CommonStatus.NO.getCode());
            UpdateWrapper<ServiceWithdrawFlow> flowUpdateWrapper = new UpdateWrapper<>();
            flowUpdateWrapper.in("cycle_add_id", List.of(cycleAddTransOrder.getCycleAddId()));
            flowUpdateWrapper.in("status", CoverChargeEnum.CommonStatus.YES.getCode());
            this.update(letaxWithdrawLogUp, updateWrapper);

            serviceAccountService.plusBalance(new AccountId(withdarwCycleAdd.getAccountId()),
                    new Amount(withdarwCycleAdd.getTotal()));
        }


        //申请中
        if (LetaxWithdrawStatusEnum.APPLY.getCode().equals(withdarwCycleAdd.getWithdrawStatus()) ||
                LetaxWithdrawStatusEnum.PASS.getCode().equals(withdarwCycleAdd.getWithdrawStatus()) ||
                LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode().equals(withdarwCycleAdd.getWithdrawStatus())) {

            serviceAccountService.rollbackFreezeBalance(new AccountId(withdarwCycleAdd.getAccountId()),
                    new Amount(withdarwCycleAdd.getTotal()), ProfitTypeEnum.ls_withdraw,
                    withdarwCycleAdd.getId(), withdarwCycleAdd.getId());
        }


        //更新服务费体现周期累计记录 失败
        withdarwCycleAdd.changeStatus(LetaxWithdrawStatusEnum.PUTFAIL);
        serviceWithdarwCycleAddService.updateById(withdarwCycleAdd);


    }




    /**
     * 更新打款成功状态
     */
    public int updateSuccessWithdarw(List<PersonGiveResult> successCycleAddIdList, String withdrawer, String channel) {
        if (CollectionUtil.isEmpty(successCycleAddIdList)) {
            return 0;
        }
        ServiceLetaxWithdrawLog letaxWithdrawLogUp = new ServiceLetaxWithdrawLog();
        letaxWithdrawLogUp.setStatus(LetaxWithdrawStatusEnum.PUT.getCode());

        List<Integer> successIdList = successCycleAddIdList.stream().map(PersonGiveResult::getCycleAddId).collect(Collectors.toList());
        UpdateWrapper<ServiceLetaxWithdrawLog> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("cycle_add_id", successIdList);
        updateWrapper.in("status", LetaxWithdrawStatusEnum.PASS.getCode(), LetaxWithdrawStatusEnum.PUTFAIL.getCode(), LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode());
        this.update(letaxWithdrawLogUp, updateWrapper);

        for (PersonGiveResult personGiveResult : successCycleAddIdList) {
            ServiceWithdarwCycleAdd withdarwCycleAddUp = new ServiceWithdarwCycleAdd();
            withdarwCycleAddUp.setId(personGiveResult.getCycleAddId());
            withdarwCycleAddUp.setWithdrawStatus(LetaxWithdrawStatusEnum.PUT.getCode());
            withdarwCycleAddUp.setWithdrawTime(new Date());
            withdarwCycleAddUp.setWithdrawer(withdrawer);
            withdarwCycleAddUp.setChannel(channel);
            //网银流水号
            withdarwCycleAddUp.setBankFlow(personGiveResult.getMsg());
            withdarwCycleAddUp.setRemark("打款成功");
            serviceWithdarwCycleAddService.updateById(withdarwCycleAddUp);

            this.saveWithdrawFlow(personGiveResult, withdrawer, channel, CoverChargeEnum.CommonStatus.YES.getCode(), "");

            //打款成功，扣除冻结金额
            accountService.updateBalanceForSuccess(personGiveResult.getAccountId(),
                    personGiveResult.getAmount(), ProfitTypeEnum.ls_withdraw, personGiveResult.getCycleAddId(), personGiveResult.getCycleAddId());

            //发送站内信
            String bankNo = personGiveResult.getBankNo();
            //String SendContent = "您的服务费申请已发放至尾号为【" + bankNo.substring(bankNo.length() - 4) + "】的银行卡，请注意查收。";

            //发送短信
            //  String MessageContent = "亲爱的ABMer，";
            //模板
            //Integer templateId = MessageTemplateIdEnum.ABM.getCode();//默认ABM

//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(personGiveResult.getPlatformCode())) {
////                userMessageClient.sendDtServiceFeeMessage(personGiveResult.getIdCode(), "服务费发放通知"
////                        , SendContent, true, true, false);
//            } else {
            //    MessageContent = "亲爱的服务商，";
            //  templateId = MessageTemplateIdEnum.DT.getCode();
            //}
//
//            MessageContent += "您本月的服务费申请已发放至尾号【" + bankNo.substring(bankNo.length() - 4) + "】银行卡，请注意查收。如有其他疑问，请在线咨询ABM客服。";

            UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(new UserIdCode(personGiveResult.getIdCode()), null);

            smsBizService.sendChargeDistributeSuccess(userInfo.getMobile(), bankNo.substring(bankNo.length() - 4));
            //userMessageClient.sendMobileMessageByTemplate(personGiveResult.getIdCode(), templateId, MessageContent);
        }
        return successCycleAddIdList.size();
    }

    /**
     * 记录打款流水
     */
    private void saveWithdrawFlow(PersonGiveResult personGiveResult, String withdrawer, String channel, int status, String msg) {
        ServiceWithdrawFlow serviceWithdrawFlow = new ServiceWithdrawFlow();
        serviceWithdrawFlow.setAmount(personGiveResult.getAmount());
        serviceWithdrawFlow.setChannel(channel);
        serviceWithdrawFlow.setCycleAddId(personGiveResult.getCycleAddId());
        serviceWithdrawFlow.setIdcardName(personGiveResult.getIdcardName());
        serviceWithdrawFlow.setIdCode(personGiveResult.getIdCode());
        serviceWithdrawFlow.setPlatformCode(personGiveResult.getPlatformCode());
        serviceWithdrawFlow.setStatus(status);
        serviceWithdrawFlow.setWithdrawer(withdrawer);
        serviceWithdrawFlow.setWithdrawTime(LocalDateTime.now());
        serviceWithdrawFlow.setRemark(msg);
        withdrawFlowService.save(serviceWithdrawFlow);
    }

    /**
     * 更新打款失败状态
     */
    public int updateFailWithdarw(List<PersonGiveResult> failCycleAddIdList, String withdrawer, String channel) {
        if (CollectionUtil.isEmpty(failCycleAddIdList)) {
            return 0;
        }

        ServiceLetaxWithdrawLog letaxWithdrawLogUp = new ServiceLetaxWithdrawLog();
        letaxWithdrawLogUp.setStatus(LetaxWithdrawStatusEnum.PUTFAIL.getCode());

        List<Integer> successIdList = failCycleAddIdList.stream().map(PersonGiveResult::getCycleAddId).collect(Collectors.toList());
        UpdateWrapper<ServiceLetaxWithdrawLog> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("cycle_add_id", successIdList);
        updateWrapper.in("status", LetaxWithdrawStatusEnum.PASS.getCode(), LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode());

        this.update(letaxWithdrawLogUp, updateWrapper);

        for (PersonGiveResult personGiveResult : failCycleAddIdList) {
            this.saveWithdrawFlow(personGiveResult, withdrawer, channel, CoverChargeEnum.CommonStatus.NO.getCode(), personGiveResult.getMsg());

            ServiceWithdarwCycleAdd withdarwCycleAddUp = new ServiceWithdarwCycleAdd();
            withdarwCycleAddUp.setId(personGiveResult.getCycleAddId());
            withdarwCycleAddUp.setWithdrawStatus(LetaxWithdrawStatusEnum.PUTFAIL.getCode());
            withdarwCycleAddUp.setWithdrawTime(new Date());
            withdarwCycleAddUp.setWithdrawer(withdrawer);
            withdarwCycleAddUp.setChannel(channel);
            withdarwCycleAddUp.setRemark(personGiveResult.getMsg());
            serviceWithdarwCycleAddService.updateById(withdarwCycleAddUp);

            //冻结余额回滚
            accountService.rollbackFreezeBalance(new AccountId(personGiveResult.getAccountId()), new Amount(personGiveResult.getAmount()),
                    ProfitTypeEnum.ls_withdraw, personGiveResult.getCycleAddId(), personGiveResult.getCycleAddId());


            //发送站内信
//            String MessageContent = "亲爱的ABMer，";
//            Integer templateId = MessageTemplateIdEnum.ABM.getCode();//默认ABM
//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(personGiveResult.getPlatformCode())) {
////                userMessageClient.sendDtServiceFeeMessage(personGiveResult.getIdCode(),
////                        "服务费发放通知", "您的服务费申请发放失败，请前往申请记录查看详情。", true, true, false);
//            } else {
//                MessageContent = "亲爱的服务商，";
//                templateId = MessageTemplateIdEnum.DT.getCode();
//            }
//
//            MessageContent += "您本月的服务费申请发放失败，为避免打款时效延长，请您尽快前往申请记录查看。如有其他疑问，请在线咨询ABM客服。";

            UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(new UserIdCode(personGiveResult.getIdCode()), null);
            smsBizService.sendChargeDistributeFail(userInfo.getMobile());
            //userMessageClient.sendMobileMessageByTemplate(personGiveResult.getIdCode(), templateId, MessageContent);
        }
        return failCycleAddIdList.size();
    }

    /**
     * 代发或者查询更新打款失败状态
     */
    public int updateFailWithdarwPay(List<PersonGiveResult> failCycleAddIdList, String withdrawer, String channel) {
        if (CollectionUtil.isEmpty(failCycleAddIdList)) {
            return 0;
        }

        //更新用户审核通过和打款失败-用户已修改
        List<Integer> statusList = Lists.newArrayList();
        statusList.add(LetaxWithdrawStatusEnum.PASS.getCode());
        statusList.add(LetaxWithdrawStatusEnum.PUTFAIL_MODIFY.getCode());

        ServiceLetaxWithdrawLog letaxWithdrawLogUp = new ServiceLetaxWithdrawLog();
        letaxWithdrawLogUp.setStatus(LetaxWithdrawStatusEnum.PUTFAIL.getCode());

        List<Integer> failIdList = failCycleAddIdList.stream().map(PersonGiveResult::getCycleAddId).collect(Collectors.toList());
        UpdateWrapper<ServiceLetaxWithdrawLog> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("cycle_add_id", failIdList);
        updateWrapper.in("status", statusList);

        this.update(letaxWithdrawLogUp, updateWrapper);

        for (PersonGiveResult personGiveResult : failCycleAddIdList) {
            this.saveWithdrawFlow(personGiveResult, withdrawer, channel, CoverChargeEnum.CommonStatus.NO.getCode(), personGiveResult.getMsg());

            ServiceWithdarwCycleAdd withdarwCycleAddUp = new ServiceWithdarwCycleAdd();
            withdarwCycleAddUp.setId(personGiveResult.getCycleAddId());
            withdarwCycleAddUp.setWithdrawStatus(LetaxWithdrawStatusEnum.PUTFAIL.getCode());
            withdarwCycleAddUp.setWithdrawTime(new Date());
            withdarwCycleAddUp.setWithdrawer(withdrawer);
            withdarwCycleAddUp.setChannel(channel);
            withdarwCycleAddUp.setRemark(personGiveResult.getMsg());
            serviceWithdarwCycleAddService.updateById(withdarwCycleAddUp);

            //冻结余额回滚
            accountService.rollbackFreezeBalance(new AccountId(personGiveResult.getAccountId()), new Amount(personGiveResult.getAmount()),
                    ProfitTypeEnum.ls_withdraw, personGiveResult.getCycleAddId(), personGiveResult.getCycleAddId());


            //发送站内信
//            String MessageContent = "亲爱的ABMer，";
//            Integer templateId = MessageTemplateIdEnum.ABM.getCode();//默认ABM
//            if (CoverChargeEnum.ServiceAccountType.CUSTOMER_TYPE.getPlatform().equals(personGiveResult.getPlatformCode())) {
////                userMessageClient.sendDtServiceFeeMessage(personGiveResult.getIdCode(),
////                        "服务费发放通知", "您的服务费申请发放失败，请前往申请记录查看详情。", true, true, false);
//            } else {
//                MessageContent = "亲爱的服务商，";
//                templateId = MessageTemplateIdEnum.DT.getCode();
//            }
//
//            MessageContent += "您本月的服务费申请发放失败，为避免打款时效延长，请您尽快前往申请记录查看。如有其他疑问，请在线咨询ABM客服。";

            UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(new UserIdCode(personGiveResult.getIdCode()), null);
            smsBizService.sendChargeDistributeFail(userInfo.getMobile());

            //userMessageClient.sendMobileMessageByTemplate(personGiveResult.getIdCode(), templateId, MessageContent);
        }
        return failCycleAddIdList.size();
    }

    /**
     * 商户中文转平台编号
     */
    private String parsePlatformCode(String merchant) {
        if (CoverChargeEnum.ServiceAccountType.MANAGE_TYPE.getMerchant().equals(merchant)) {
            return CoverChargeEnum.ServiceAccountType.MANAGE_TYPE.getPlatform();
        } else {
            return merchant;
        }
    }

    @Override
    public Page<AdminRegistrationQueryVo> queryPagePerson(Page page, String idCode, String name, String cardNo, String platform, Integer status, String startDate, String endDate) {
        QueryWrapper<ServiceLetaxWithdrawLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(idCode), "id_code", idCode);
        queryWrapper.eq(StringUtils.isNotBlank(platform), "platform_code", platform);
        queryWrapper.eq(status != null, "status", status);
        queryWrapper.ge(StringUtils.isNotBlank(startDate), "created_at", startDate);
        queryWrapper.lt(StringUtils.isNotBlank(endDate), "created_at", endDate);
        queryWrapper.like(StringUtils.isNotBlank(name), "registered_info", name);
        queryWrapper.like(StringUtils.isNotBlank(cardNo), "registered_info", cardNo);
        queryWrapper.eq("auth_type", "person");
        queryWrapper.orderByDesc("id");
        IPage<ServiceLetaxWithdrawLog> pagelist = serviceLetaxWithdrawLogMapper.selectPage(page, queryWrapper);
        List<ServiceLetaxWithdrawLog> logs = pagelist.getRecords();

        List<UserIdCode> idList = new ArrayList<>();
        for (ServiceLetaxWithdrawLog log : logs) {
            idList.add(new UserIdCode(log.getIdCode()));
        }

        Map<UserIdCode, UserInfo> userMap = userService.queryUserMap(idList);

        List<AdminRegistrationQueryVo> querys = new ArrayList<>();
        for (ServiceLetaxWithdrawLog log : logs) {
            AdminRegistrationQueryVo query = new AdminRegistrationQueryVo();
            BeanUtils.copyProperties(log, query);
            JSONObject result = JSONObject.parseObject(log.getRegisteredInfo());
            UserIdCode userId = new UserIdCode(query.getIdCode());
            if (userMap.containsKey(userId)) {
                UserInfo userVO = userMap.get(userId);
                query.setMobile(userVO.getMobile());
                query.setName(userVO.getName());
            }
            List<WithdrawalReason> withdrawalReasonList = JSON.parseArray(log.getReason(), WithdrawalReason.class);
            query.setApplyReson(withdrawalReasonList);
            query.setIdcardName(result.getString("idcard_name"));
            query.setBankName(result.getString("bank_name"));
            query.setBankNo(result.getString("bank_no"));
            querys.add(query);
        }
        page.setRecords(querys);
        page.setTotal(pagelist.getTotal());
        return page;
    }

    /**
     * 更新提现申请和打款流水备注
     *
     * @param withdrawFlowId 打款流水ID
     * @param remark         备注
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWithdrawRemark(Integer withdrawFlowId, String remark) {
        ServiceWithdrawFlow withdrawFlow = withdrawFlowService.getById(withdrawFlowId);
        Assert.notNull(withdrawFlow, "没有查询到响应的打款流水");

        ServiceWithdrawFlow serviceWithdrawFlowUp = new ServiceWithdrawFlow();
        serviceWithdrawFlowUp.setId(withdrawFlowId);
        serviceWithdrawFlowUp.setRemark(remark);
        boolean flag = withdrawFlowService.updateById(serviceWithdrawFlowUp);
        Assert.isTrue(flag, "更新打款流水备注失败");

        ServiceWithdrawFlow withdrawFlowParam = new ServiceWithdrawFlow();
        withdrawFlowParam.setCycleAddId(withdrawFlow.getCycleAddId());
        QueryWrapper<ServiceWithdrawFlow> queryWrapper = new QueryWrapper<>(withdrawFlowParam);
        queryWrapper.orderByDesc("withdraw_time");
        List<ServiceWithdrawFlow> list = withdrawFlowService.list(queryWrapper);
        //最近一条而且打款失败，需要更新提现申请的备注
        if (list.get(0).getId().equals(withdrawFlowId) && CoverChargeEnum.CommonStatus.NO.getCode().equals(withdrawFlow.getStatus())) {
            ServiceWithdarwCycleAdd serviceWithdarwCycleAddUp = new ServiceWithdarwCycleAdd();
            serviceWithdarwCycleAddUp.setId(withdrawFlow.getCycleAddId());
            serviceWithdarwCycleAddUp.setRemark(remark);
            serviceWithdarwCycleAddService.updateById(serviceWithdarwCycleAddUp);
        }

    }

    @Override
    public DealSinglePayResult updateStatusLeTax(PersonalGiveVo personalGiveVo) throws Exception {
        List<PersonGiveResult> successCycleAddIdList = new ArrayList<>();
        List<PersonGiveResult> failCycleAddIdList = new ArrayList<>();
        DealSinglePayResult dealSinglePayResult = new DealSinglePayResult();
        // 所属周期
        String cycleDate = personalGiveVo.getCycleDate();
        // 代理ID
        Integer idCode = personalGiveVo.getIdCode();
        // 平台
        String platformCode = personalGiveVo.getPlatformCode();
        // 银行卡号
        String bankNo = personalGiveVo.getBankNo();
        // 金额
        BigDecimal money = personalGiveVo.getMoney();
        //备注
        String msg = personalGiveVo.getRemark();
        //校验记录是否存在，且数据是否一致
        PersonalGiveQuery personalGiveQuery = new PersonalGiveQuery();
        personalGiveQuery.setIdCode(idCode);
        personalGiveQuery.setCycleDate(cycleDate);
        personalGiveQuery.setPlatformCode(platformCode);
        Page<PersonalGiveVo> pageList = this.queryPersonalGiveList(new Page<>(1, 1), personalGiveQuery);
        if (CollectionUtil.isEmpty(pageList.getRecords())) {
            throw new Exception("此条记录不存在");
        }
        PersonalGiveVo personalGive = pageList.getRecords().get(0);
        if (PersonalGiveStatusEnum.APPLY.getCode().equals(personalGive.getStatus())) {
            throw new Exception("此条记录未审核完成,无法更新状态");
        }
        if (personalGive.getMoney().compareTo(money) != 0) {
            throw new Exception("此条记录应付金额不一致");
        }
        if (!personalGive.getBankNo().equals(bankNo)) {
            throw new Exception("此条记录银行卡号不一致");
        }
        if (StringUtils.isNotEmpty(personalGiveVo.getIdcardNo())) {
            if (!personalGive.getIdcardNo().equals(personalGiveVo.getIdcardNo())) {
                throw new Exception("此条记录身份证号不一致");
            }
        }

        if (!SignIdentityEnum.regist_soho.getDesc().equals(personalGiveVo.getAuthType())) {
            throw new Exception("不是乐税注册个体户提现无法修改");
        }
        //定义交易结果返回
        ServiceWithdarwCycleAddTransOrder serviceWithdarwCycleAddTransOrder;
        //查找处理中和未知的
        serviceWithdarwCycleAddTransOrder = serviceWithdarwCycleAddTransOrderService.getProcessOrUnKnow(personalGiveVo.getCycleAddId(), true);
        //查找成功的
        if (Objects.isNull(serviceWithdarwCycleAddTransOrder)) {
            serviceWithdarwCycleAddTransOrder = serviceWithdarwCycleAddTransOrderService.getSuccessful(personalGiveVo.getCycleAddId());
        }
        if (Objects.isNull(serviceWithdarwCycleAddTransOrder)) {
            throw new Exception("没有打款交易记录");
        }

        //调用第三方代发或者查询
        ServiceWithdarwCycleAddDto cycleAdd = new ServiceWithdarwCycleAddDto();
        cycleAdd.setId(serviceWithdarwCycleAddTransOrder.getCycleAddId());
        cycleAdd.setBusinessNo(serviceWithdarwCycleAddTransOrder.getBusinessNo());
        cycleAdd.setAddTransOrderId(serviceWithdarwCycleAddTransOrder.getId());
        cycleAdd.setNum(serviceWithdarwCycleAddTransOrder.getNum());
        cycleAdd.setMerDate(serviceWithdarwCycleAddTransOrder.getCreatedTime().toString());
        cycleAdd.setIdCode(personalGive.getIdCode());

        //打款数据准备
        PersonalGiveVo personalGiveVoQuery = new PersonalGiveVo();
        personalGiveVoQuery.setAddTransOrderId(serviceWithdarwCycleAddTransOrder.getId());
        personalGiveVoQuery.setBankNo(personalGive.getBankNo());
        personalGiveVoQuery.setIdcardName(personalGive.getIdcardName());
        personalGiveVoQuery.setMoney(personalGive.getPassMoney());
        personalGiveVoQuery.setCycleAddId(personalGive.getCycleAddId());
        personalGiveVoQuery.setAccountId(personalGive.getAccountId());
        personalGiveVoQuery.setIdCode(idCode);
        personalGiveVoQuery.setPlatformCode(platformCode);
        personalGiveVoQuery.setReturnMsg(msg);
        personalGiveVoQuery.setWithdrawer(personalGiveVo.getOperator());

        try {
            dealSinglePayResult = serviceWithdarwCycleAddServiceImpl.dealSinglePayQuery(cycleAdd, personalGiveVoQuery);
        } catch (Exception e) {
            log.error("[服务费后台][个人收益打款申请记录][变更打款][调用代发查询服务失败]", e);
            throw new Exception("调用代发查询服务或者更新周期信息失败");
        }

        return dealSinglePayResult;
    }


    @Override
    public void updatePersonalGive(PersonalGiveVo personalGiveVo) throws Exception {
        List<PersonGiveResult> successCycleAddIdList = new ArrayList<>();
        List<PersonGiveResult> failCycleAddIdList = new ArrayList<>();
        // 所属周期
        String cycleDate = personalGiveVo.getCycleDate();
        // 代理ID
        Integer idCode = personalGiveVo.getIdCode();
        // 平台
        String platformCode = personalGiveVo.getPlatformCode();
        // 银行卡号
        String bankNo = personalGiveVo.getBankNo();
        // 金额
        BigDecimal money = personalGiveVo.getMoney();
        // 状态
        Integer status = personalGiveVo.getStatus();
        //备注
        String msg = personalGiveVo.getRemark();
        //校验记录是否存在，且数据是否一致
        PersonalGiveQuery personalGiveQuery = new PersonalGiveQuery();
        personalGiveQuery.setIdCode(idCode);
        personalGiveQuery.setCycleDate(cycleDate);
        personalGiveQuery.setPlatformCode(platformCode);
        Page<PersonalGiveVo> pageList = this.queryPersonalGiveList(new Page<>(1, 1), personalGiveQuery);
        if (CollectionUtil.isEmpty(pageList.getRecords())) {
            throw new Exception("此条记录不存在");
        }
        PersonalGiveVo personalGive = pageList.getRecords().get(0);
        if (PersonalGiveStatusEnum.APPLY.getCode().equals(personalGive.getStatus())) {
            throw new Exception("此条记录未审核完成,无法更新状态");
        }
        if (PersonalGiveStatusEnum.PUT.getCode().equals(personalGive.getStatus())) {
            throw new Exception("该记录已经改为已发放，请勿重复操作");
        }
        if (PersonalGiveStatusWebEnum.PAY_FAILURE.getCode().equals(status) && PersonalGiveStatusEnum.PUTFAIL.getCode().equals(personalGive.getStatus())) {
            throw new Exception("该记录已经改为发放失败，请勿重复操作");
        }
        if (personalGive.getMoney().compareTo(money) != 0) {
            throw new Exception("此条记录应付金额不一致");
        }
//        if (!personalGive.getBankNo().equals(bankNo)) {
//            throw new Exception("此条记录银行卡号不一致");
//        }
        if (StringUtils.isNotEmpty(personalGiveVo.getIdcardNo())) {
            if (!personalGive.getIdcardNo().equals(personalGiveVo.getIdcardNo())) {
                throw new Exception("此条记录身份证号不一致");
            }
        }
        if (PersonalGiveStatusWebEnum.PAY_FAILURE.getCode().equals(status)) {
            //处理打款失败状态数据
            failCycleAddIdList.add(new PersonGiveResult(personalGive.getBankNo(), personalGive.getIdcardName(), personalGive.getPassMoney(),
                    personalGive.getCycleAddId(), personalGive.getAccountId(), idCode, platformCode, msg));
        } else if (PersonalGiveStatusWebEnum.PAY_SUCCESS.getCode().equals(status)) {
            //处理打款成功状态数据
            successCycleAddIdList.add(new PersonGiveResult(personalGive.getBankNo(), personalGive.getIdcardName(), personalGive.getPassMoney(), personalGive.getCycleAddId(),
                    personalGive.getAccountId(), idCode, platformCode, StringUtils.isNotEmpty(personalGiveVo.getBankFlow()) ? personalGiveVo.getBankFlow() : msg));
        }
        PersonalGiveImport personalGiveImport = new PersonalGiveImport();
        personalGiveImport.setCreator(personalGiveVo.getOperator());
        personalGiveImport.setChannel(personalGiveVo.getChannel());
        dealData(successCycleAddIdList, failCycleAddIdList, personalGiveImport);
    }

    @Override
    public IPage<ServiceLetaxWithdrawLogVo> queryPageByCycleAddId(Page page, Integer cycleAddId) {

        return serviceLetaxWithdrawLogMapper.queryPageByCycleAddId(page, cycleAddId);
    }


    @Override
    public Boolean isExistLeTaxWithdraw(Long idCode) {
        QueryWrapper<ServiceLetaxWithdrawLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id_code", idCode);
        queryWrapper.notIn("status", LetaxWithdrawStatusEnum.PUT.getCode(), LetaxWithdrawStatusEnum.REJECT.getCode(), LetaxWithdrawStatusEnum.CANCEL.getCode());
        List<ServiceLetaxWithdrawLog> lists = serviceLetaxWithdrawLogMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(lists)) {
            return Boolean.FALSE;
        }
        return lists.size() > 0;
    }


    @Override
    public BigDecimal sumMoney(Integer cycleAddId, Integer status) {
        return serviceLetaxWithdrawLogMapper.sumMoney(cycleAddId, status);
    }

    /**
     * 根据周期id获取最后提现明细数据
     *
     * @param cycleAddId 代理id
     * @return WithdrawLogRecordVo
     * @auth cj
     */
    @Override
    public WithdrawLogRecordVo queryLogByCycleAddId(Integer cycleAddId) {
        return serviceLetaxWithdrawLogMapper.queryLogByCycleAddId(cycleAddId);
    }

    /**
     * 根据周期id获取是否是注册个体户提现记录
     *
     * @param cycleAddId 代理id
     * @return Boolean
     * @auth cj
     */
    @Override
    public Boolean isLeTaxUser(Integer cycleAddId) {
        Boolean isLeTaxUser = true;
        WithdrawLogRecordVo withdrawLogRecordVo = serviceLetaxWithdrawLogMapper.queryLogByCycleAddId(cycleAddId);
        if (Objects.isNull(withdrawLogRecordVo)) {
            isLeTaxUser = false;
        }
        if (!withdrawLogRecordVo.getAuthType().equals(SignIdentityEnum.regist_soho.getCode())) {
            isLeTaxUser = false;
        }
        return isLeTaxUser;
    }

    /**
     * 代发打款成功或者失败
     *
     * @param personalGiveVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer dealPayReturnData(PersonalGiveVo personalGiveVo) {
        //更新数据准备
        ServiceWithdarwCycleAddTransOrder withdarwCycleAddTransOrderUpdate = new ServiceWithdarwCycleAddTransOrder();
        withdarwCycleAddTransOrderUpdate.setId(personalGiveVo.getAddTransOrderId());
        withdarwCycleAddTransOrderUpdate.setUpdatedTime(new Date());
        Integer dealNum;
        //成功
        if (personalGiveVo.getIsSuccess()) {
            List<PersonGiveResult> successCycleAddIdList = new ArrayList<>();
            successCycleAddIdList.add(new PersonGiveResult(
                    personalGiveVo.getBankNo(),
                    personalGiveVo.getIdcardName(),
                    personalGiveVo.getPassMoney(),
                    personalGiveVo.getCycleAddId(),
                    personalGiveVo.getAccountId(),
                    personalGiveVo.getIdCode(),
                    personalGiveVo.getPlatformCode(),
                    personalGiveVo.getReturnMsg()
            ));
            try {
                dealNum = updateSuccessWithdarw(successCycleAddIdList, personalGiveVo.getWithdrawer(), personalGiveVo.getChannel());
            } catch (Exception e) {
                log.error("[服务费后台][个人收益打款申请记录][周期打款][更新打款成功状态异常]", e);
                throw new ServiceException(e.getMessage());
            }
            withdarwCycleAddTransOrderUpdate.setStatus(ServiceWithdarwCycleAddTransOrderEnum.SUCCESSFUL.getCode());
        } else {
            List<PersonGiveResult> failCycleAddIdList = new ArrayList<>();
            //失败
            failCycleAddIdList.add(new PersonGiveResult(
                    personalGiveVo.getBankNo(),
                    personalGiveVo.getIdcardName(),
                    personalGiveVo.getPassMoney(),
                    personalGiveVo.getCycleAddId(),
                    personalGiveVo.getAccountId(),
                    personalGiveVo.getIdCode(),
                    personalGiveVo.getPlatformCode(),
                    personalGiveVo.getReturnMsg()
            ));
            try {
                dealNum = updateFailWithdarwPay(failCycleAddIdList, personalGiveVo.getWithdrawer(), personalGiveVo.getChannel());
            } catch (Exception e) {
                log.error("[服务费后台][个人收益打款申请记录][周期打款][更新打款成功状态异常]", e);
                throw new ServiceException(e.getMessage());
            }
            withdarwCycleAddTransOrderUpdate.setStatus(ServiceWithdarwCycleAddTransOrderEnum.FAILURE.getCode());

        }
        serviceWithdarwCycleAddTransOrderService.updateById(withdarwCycleAddTransOrderUpdate);
        return dealNum;
    }

    /**
     * 查询个体发放列表
     *
     * @param page              页码
     * @param personalGiveQuery 参数
     */
    @Override
    public Page<PersonalGiveVo> queryPersonalGiveAllList(Page<PersonalGiveVo> page, PersonalGiveQuery personalGiveQuery) {
        List<PersonalGiveVo> list = serviceLetaxWithdrawLogMapper.queryPersonalGiveList(page, personalGiveQuery);
        page.setRecords(list);
        return page;
    }

    /**
     * 查询个体发放列表
     *
     * @param page              页码
     * @param personalGiveQuery 参数
     */
    @Override
    public Page<PersonalGiveVo> queryPersonalGiveAllListAllPaid(Page<PersonalGiveVo> page, PersonalGiveQuery personalGiveQuery) {
        List<PersonalGiveVo> list = serviceLetaxWithdrawLogMapper.queryPersonalGiveListAllPaid(page, personalGiveQuery);
        page.setRecords(list);
        return page;
    }

    /**
     * 修改提现记录中的乐税状态
     *
     * @param letaxStatus
     * @param cycleAddId
     */
    @Override
    public void updateLetaxStatus(Integer letaxStatus, Integer cycleAddId) {
        Date nowDate = new Date();
        serviceLetaxWithdrawLogMapper.updateLetaxStatus(letaxStatus, nowDate, cycleAddId);
    }

    /**
     * 更新提现记录和交易记录表
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateLogAndTransOrder(ServiceWithdarwCycleAddDto cycleAdd) {
        //更新提现记录
        updateLetaxStatus(LetaxWithdrawMerchantStatusEnum.YES.getCode(), cycleAdd.getId());
        log.error("[服务费后台][个人收益打款申请记录][周期打款][" + cycleAdd.getAlertTitle() + "商户状态为注销]");

        //更新交易记录表
        serviceWithdarwCycleAddTransOrderService.updateByQuery(cycleAdd.getAddTransOrderId(), cycleAdd.getNum() + 1, ServiceWithdarwCycleAddTransOrderEnum.FAILURE.getCode(), "商户状态为注销");
    }

    /**
     * 修改提现记录中的乐税状态
     *
     * @param date
     * @param startDateStr
     * @param endDateStr
     */
    @Override
    public QueryPayDataResult getPayData(String date, String startDateStr, String endDateStr) {
        QueryPayDataResult queryPayDataResult = new QueryPayDataResult();
        queryPayDataResult.setNotPayMoney(0);
        queryPayDataResult.setPayFailureNum(0);
        queryPayDataResult.setPaySuccessNum(0);

        //参数拼接
        PersonalGiveQuery personalGiveQuery = new PersonalGiveQuery();
        personalGiveQuery.setAuthType(SignIdentityEnum.regist_soho.getCode());
        personalGiveQuery.setCycleDate(date);
        personalGiveQuery.setStartDate(startDateStr);
        personalGiveQuery.setEndDate(endDateStr);
        //查询符合条件的周期记录总数
        Page<PersonalGiveVo> pageResultTotal = queryPersonalGiveAllList(new Page<>(1, 1), personalGiveQuery);

        //获取总数
        long count = pageResultTotal.getTotal();

        log.info("[服务费后台][注册个体户,个人提现打款查询]，count={}", count);

        //获取页数
        int page = Math.toIntExact((count / PAGE_SIZE + (count % PAGE_SIZE > 0 ? 1 : 0)));

        log.info("[服务费后台][注册个体户,个人提现打款查询]，page={}", page);

        //分页获取符合条件页数
        for (int i = 1; i <= page; i++) {
            Page<PersonalGiveVo> pageResult = queryPersonalGiveAllList(new Page<>(i, PAGE_SIZE), personalGiveQuery);
            List<PersonalGiveVo> list = pageResult.getRecords();

            if (!CollectionUtils.isEmpty(list)) {
                for (PersonalGiveVo vo : list) {
                    if (ServiceWithdarwCycleAddEnum.NOT_PAY.getCode().equals(vo.getStatus())) {
                        queryPayDataResult.setNotPayMoney(queryPayDataResult.getNotPayMoney() + 1);
                    } else if (ServiceWithdarwCycleAddEnum.HAVE_PAY.getCode().equals(vo.getStatus())) {
                        queryPayDataResult.setPaySuccessNum(queryPayDataResult.getPaySuccessNum() + 1);
                    } else if (ServiceWithdarwCycleAddEnum.PAY_FAILURE.getCode().equals(vo.getStatus())) {
                        queryPayDataResult.setPayFailureNum(queryPayDataResult.getPayFailureNum() + 1);
                    }
                }
            }
        }
        return queryPayDataResult;
    }

    @Override
    public Page<PersonalGiveVo> queryPersonalGiveAllListWithIds(Page<PersonalGiveVo> page, PersonalGiveQuery personalGiveQuery) {
        List<PersonalGiveVo> list = serviceLetaxWithdrawLogMapper.queryPersonalGiveListWithIds(page, personalGiveQuery);
        page.setRecords(list);
        return page;
    }

    @Override
    public PersonalGiveMoneyTotalVo queryPersonalGiveMoneyTotal(PersonalGiveQuery personalGiveQuery) {
        PersonalGiveMoneyTotalVo result = new PersonalGiveMoneyTotalVo();
        if (StringUtils.isNotEmpty(personalGiveQuery.getCycleDate()) && !"null".equals(personalGiveQuery.getCycleDate())) {
            String cycleDay = ConfigUtil.getConfig().getString("withdraw.cycle.day", "10");
            String startDateStr = DateTimeUtils.parseDateAsString(
                    DateTimeUtils.addMonths(DateUtil.parse(personalGiveQuery.getCycleDate(), DateTimeUtils.MONTH_FORMAT), -1),
                    DateTimeUtils.MONTH_FORMAT)
                    + "-" + (Integer.parseInt(cycleDay) + 1) + " 00:00:00";

            String endDateStr = DateTimeUtils.parseDateAsString(
                    DateUtil.parse(personalGiveQuery.getCycleDate(), DateTimeUtils.MONTH_FORMAT),
                    DateTimeUtils.MONTH_FORMAT)
                    + "-" + cycleDay + " 23:59:59";
            personalGiveQuery.setStartDate(startDateStr);
            personalGiveQuery.setEndDate(endDateStr);
        } else {
            personalGiveQuery.setCycleDate(null);
        }

        if (StringUtils.isNotEmpty(personalGiveQuery.getMobile())) {
            try {
                UserInfo userInfo = userDocService.searchUserByIdCodeOrMobile(null, personalGiveQuery.getMobile());
                Assert.isTrue(userInfo != null, "没有查询到用户信息");
                personalGiveQuery.setIdCode(Integer.parseInt(userInfo.getIdCode() + ""));
            } catch (Exception e) {
                throw new InterfaceException(USER_NOT_EXIST);
            }
        }

        List<PersonalGiveVo> list = serviceLetaxWithdrawLogMapper.queryPersonalGiveMoneyList(personalGiveQuery);

        BigDecimal passMoneyTotal = BigDecimal.ZERO;
        BigDecimal feeTotal = BigDecimal.ZERO;
        BigDecimal moneyTotal = BigDecimal.ZERO;
        for (PersonalGiveVo personalGiveVo : list) {
            BigDecimal passMoney = personalGiveVo.getPassMoney();
            passMoneyTotal = passMoneyTotal.add(passMoney);
            BigDecimal fee = personalGiveVo.getPassMoney().multiply(personalGiveVo.getRatio());
            feeTotal = feeTotal.add(fee);
            moneyTotal = moneyTotal.add(passMoney.subtract(fee));
        }
        result.setPassMoneyTotal(passMoneyTotal);
        result.setFeeTotal(feeTotal);
        result.setMoneyTotal(moneyTotal);
        return result;
    }
}
